package com.jht.btconnect.adapter;


import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.jht.btconnect.R;
import com.jht.btconnect.common.AttributeLookup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

public class ExpandableLvBTAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<BluetoothGattService> servicesGroup = new ArrayList<>();
    private List<BluetoothGattCharacteristic> characteristicsChild = new ArrayList<>();
    private HashMap<String, List<BluetoothGattCharacteristic>> map = new HashMap<>();
    private AttributeLookup attributeLookup = null;

    public ExpandableLvBTAdapter(Context context) {
        this.context = context;
        attributeLookup = new AttributeLookup(context);
    }

    @Override
    public int getGroupCount() {
        return servicesGroup.size();
    }

    @Override
    public int getChildrenCount(int groupIndex) {
        String uuidStr = servicesGroup.get(groupIndex).getUuid().toString();
        return map.get(uuidStr).size();
    }

    @Override
    public Object getGroup(int groupIndex) {
        return servicesGroup.get(groupIndex);
    }

    @Override
    public Object getChild(int groupIndex, int childIndex) {
        String uuidStr = servicesGroup.get(groupIndex).getUuid().toString();
        return map.get(uuidStr).get(childIndex);
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    public void addCharacteristic(String uuidStr, List<BluetoothGattCharacteristic> bluetoothGattCharacteristics) {
        characteristicsChild = new ArrayList<>();
        for (BluetoothGattCharacteristic btCharacteristic : bluetoothGattCharacteristics) {
            characteristicsChild.add(btCharacteristic);
        }
        map.put(uuidStr, characteristicsChild);
        notifyDataSetChanged();
    }

    public void addService(BluetoothGattService service) {
        servicesGroup.add(service);
        addCharacteristic(service.getUuid().toString(), service.getCharacteristics());
    }

    public void clearAllList() {
        servicesGroup.clear();
        characteristicsChild.clear();
        map.clear();
        notifyDataSetChanged();
    }

    public void addBTServices(List<BluetoothGattService> services) {
        for (BluetoothGattService gattService : services) {
            addService(gattService);
        }
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHolder groupViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_group_lv_bt_service, parent, false);
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.mTvBtServiceName = (TextView) convertView.findViewById(R.id.tv_bt_service_name);
            groupViewHolder.mTvBtServiceUuid = (TextView) convertView.findViewById(R.id.tv_bt_service_uuid);
            convertView.setTag(groupViewHolder);
        } else {
            groupViewHolder = (GroupViewHolder) convertView.getTag();
        }
        UUID uuid = servicesGroup.get(groupPosition).getUuid();
        groupViewHolder.mTvBtServiceName.setText(attributeLookup.getService(uuid));
        groupViewHolder.mTvBtServiceUuid.setText(uuid.toString());
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildViewHolder childViewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_child_lv_bt_character, parent, false);
            childViewHolder = new ChildViewHolder();
            childViewHolder.mTvBtCharacterName = (TextView) convertView.findViewById(R.id.tv_bt_character_name);
            childViewHolder.mTvBtCharacterUuid = (TextView) convertView.findViewById(R.id.tv_bt_character_uuid);
            childViewHolder.mTvBtCharacterProperties = (TextView) convertView.findViewById(R.id.tv_bt_character_properties);
            childViewHolder.mLlCharacter = (LinearLayout) convertView.findViewById(R.id.ll_character);
            convertView.setTag(childViewHolder);

        } else {
            childViewHolder = (ChildViewHolder) convertView.getTag();
        }
        String uuidStr = servicesGroup.get(groupPosition).getUuid().toString();
        BluetoothGattCharacteristic bluetoothGattCharacteristic = map.get(uuidStr).get(childPosition);
        UUID characteristic_uuid = bluetoothGattCharacteristic.getUuid();
        childViewHolder.mTvBtCharacterName.setText(attributeLookup.getCharacteristic(characteristic_uuid));
        childViewHolder.mTvBtCharacterUuid.setText(characteristic_uuid.toString());
        int properties = bluetoothGattCharacteristic.getProperties();
        String propertiesStr = getCharacterProperties(properties);
        childViewHolder.mTvBtCharacterProperties.setText(propertiesStr);
        childViewHolder.mLlCharacter.setBackgroundColor(Color.parseColor("#9AFF9A"));
        return convertView;
    }

    public String getCharacterProperties(int properties) {
        String propertiesStr = "";
        for (int i = 0; i < 8; i++) {
            int num = -1;
            switch (i) {
                case 0:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_BROADCAST;
                    if (num == BluetoothGattCharacteristic.PROPERTY_BROADCAST) {
                        propertiesStr += "BROADCAST,";
                    }
                    break;
                case 1:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_READ;
                    if (num == BluetoothGattCharacteristic.PROPERTY_READ) {
                        propertiesStr += "READ,";
                    }
                    break;
                case 2:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE;
                    if (num == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) {
                        propertiesStr += "WRITE_NO_RESPONSE,";
                    }
                    break;
                case 3:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_WRITE;
                    if (num == BluetoothGattCharacteristic.PROPERTY_WRITE) {
                        propertiesStr += "WRITE,";
                    }
                    break;
                case 4:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_NOTIFY;
                    if (num == BluetoothGattCharacteristic.PROPERTY_NOTIFY) {
                        propertiesStr += "NOTIFY,";
                    }
                    break;
                case 5:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_INDICATE;
                    if (num == BluetoothGattCharacteristic.PROPERTY_INDICATE) {
                        propertiesStr += "INDICATE,";
                    }
                    break;
                case 6:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE;
                    if (num == BluetoothGattCharacteristic.PROPERTY_SIGNED_WRITE) {
                        propertiesStr += "SIGNED_WRITE,";
                    }
                    break;
                case 7:
                    num = properties & BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS;
                    if (num == BluetoothGattCharacteristic.PROPERTY_EXTENDED_PROPS) {
                        propertiesStr += "EXTENDED_PROPS,";
                    }
                    break;
            }
        }
        return propertiesStr;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }


    static class GroupViewHolder {
        TextView mTvBtServiceName;
        TextView mTvBtServiceUuid;
    }


    static class ChildViewHolder {
        TextView mTvBtCharacterName;
        TextView mTvBtCharacterUuid;
        TextView mTvBtCharacterProperties;
        LinearLayout mLlCharacter;

    }
}
